#include <stdio.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>

#include "../include/zbar_lib/zbar.h"
#include <jpeglib.h>
#include <jerror.h>
#include "../include/zbar.h"
#define BUF_SIZE (10*1024*1024)
extern pthread_mutex_t jpg_mutex;

static void _convert_data (const unsigned char *p_jpg_buffer, unsigned int jpg_size, int *width, int *height, void **raw)
{
	struct jpeg_decompress_struct cinfo;
	struct jpeg_error_mgr err;
	cinfo.err = jpeg_std_error(&err);
	jpeg_create_decompress(&cinfo);
	jpeg_mem_src(&cinfo, (unsigned char *)p_jpg_buffer, jpg_size);
	(void)jpeg_read_header(&cinfo, TRUE);
	cinfo.out_color_space = JCS_GRAYSCALE;
//	cinfo.two_pass_quantize = TRUE;
	(void)jpeg_start_decompress(&cinfo);
	*width = cinfo.image_width;
	*height = cinfo.image_height;
	*raw = (void *)malloc(cinfo.output_width * cinfo.output_height * 3);
	unsigned bpl = cinfo.output_width * cinfo.output_components;
	JSAMPROW buf = (void *)*raw;
	JSAMPARRAY line = &buf;
	for (; cinfo.output_scanline < cinfo.output_height; buf += bpl) 
	{
		jpeg_read_scanlines(&cinfo, line, 1);
	}
	(void)jpeg_finish_decompress(&cinfo);
	jpeg_destroy_decompress(&cinfo);
}


int  QRcodeRecognition(struct jpg_buf_t *jpg ,char *arr)
{
    pthread_mutex_lock(&jpg_mutex);

    int freadResult = jpg->len;
    //printf("%d",freadResult);
    unsigned char *p_ReadBuffer = (unsigned char *)malloc(freadResult);
    memset(p_ReadBuffer, 0, freadResult);
    memcpy(p_ReadBuffer,jpg->buf,freadResult);
    //printf("read %d \r\n", freadResult);
    
    pthread_mutex_unlock(&jpg_mutex);

    zbar_image_scanner_t *scanner = NULL;
    scanner = zbar_image_scanner_create();
    zbar_image_scanner_set_config(scanner, ZBAR_QRCODE, ZBAR_CFG_ENABLE, 1);


    /* obtain image data */
    int width = 0, height = 0;
    void *raw = NULL;

    _convert_data(p_ReadBuffer, freadResult, &width, &height, &raw);
    free(p_ReadBuffer);

    //printf("width:%d  height:%d \r\n", width, height);

    /* wrap image data */
    zbar_image_t *image = zbar_image_create();
    zbar_image_set_format(image, *(int*)"Y800");
    zbar_image_set_size(image, width, height);
    zbar_image_set_data(image, raw, width * height, zbar_image_free_data);

    /* scan the image for barcodes */
    int n = zbar_scan_image(scanner, image);
    
    /* extract results */
    const zbar_symbol_t *symbol = zbar_image_first_symbol(image);
    if(symbol == 0)
    {
        zbar_image_destroy(image);
        zbar_image_scanner_destroy(scanner);
        return 0;
    }
    for(; symbol; symbol = zbar_symbol_next(symbol)) 
    {
        /* do something useful with results */
        zbar_symbol_type_t typ = zbar_symbol_get_type(symbol);
        const char *data = zbar_symbol_get_data(symbol);
        strcpy(arr,data);
        //printf("decoded %s symbol \"%s\"\n", zbar_get_symbol_name(typ), data);
    }
    /* clean up */
    zbar_image_destroy(image);
    zbar_image_scanner_destroy(scanner);
    return 1;
}
